﻿using RotovapPlatform.Domain.Business.Storage.Entities;
using RotovapPlatform.Domain.Business.Storage.Entities.Base;
using RotovapPlatform.Domain.Business.Storage.Enums;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.Domain.Services.Storages
{
	/// <summary>
	/// 存储服务接口
	/// 定义了物料管理的业务逻辑
	/// </summary>
	public interface IStorageDomainService
	{
		/// <summary>
		/// 获取所有货架位置
		/// </summary>
		/// <returns>货架位置列表</returns>
		Task<List<StorageLocation>> GetAllShelfLocationsAsync();

		/// <summary>
		/// 获取指定货架位置
		/// </summary>
		/// <param name="locationCode">货架位置类型</param>
		/// <param name="position">货架位置编号</param>
		/// <returns>货架位置</returns>
		Task<StorageLocation?> GetShelfLocationAsync(LocationCode locationCode, int position);

		/// <summary>
		/// 根据ID获取货架位置
		/// </summary>
		/// <param name="id">货架位置ID</param>
		/// <returns>货架位置</returns>
		[Obsolete("请使用基于位置的方法 GetShelfLocationAsync(LocationCode, int) 代替")]
		Task<StorageLocation?> GetShelfLocationByIdAsync(int id);

		/// <summary>
		/// 获取所有工作站位置
		/// </summary>
		/// <param name="stationType">工作站类型</param>
		/// <returns>工作站位置列表</returns>
		Task<List<StorageLocation>> GetStationLocationsAsync(LocationCode stationType);

		/// <summary>
		/// 获取可以放置指定物品类型的空闲货架位置
		/// </summary>
		/// <param name="itemType">物品类型</param>
		/// <returns>可用的货架位置列表</returns>
		Task<List<StorageLocation>> GetAvailableShelfLocationsForItemTypeAsync(ItemType itemType);

		/// <summary>
		/// 获取已占用但有可用瓶子的货架位置
		/// </summary>
		/// <param name="bottleType">瓶子类型</param>
		/// <returns>有可用瓶子的位置列表</returns>
		Task<List<StorageLocation>> GetAvailableBottleLocationsAsync(ItemType bottleType);

		/// <summary>
		/// 获取指定瓶子类型和指定IsReserved状态的货架位置
		/// </summary>
		/// <param name="bottleType">瓶子类型</param>
		/// <param name="reservedStatus">预占位状态（0:未预占位,1:预占位但未使用,2:预占位且已使用）</param>
		/// <returns>符合条件的货架位置列表</returns>
		Task<List<StorageLocation>> GetBottleLocationsByReservedStatusAsync(ItemType bottleType, int reservedStatus);

		/// <summary>
		/// 将物品放入指定货架位置
		/// </summary>
		/// <param name="locationId">货架位置ID</param>
		/// <param name="item">物品</param>
		/// <returns>更新后的货架位置</returns>
		[Obsolete("请使用基于位置的方法 PlaceItemByPositionAsync(LocationCode, int, IStorageItem) 代替")]
		Task<StorageLocation> PlaceItemAsync(int locationId, IStorageItem item);

		/// <summary>
		/// 将物品放入指定货架位置（通过位置编号）
		/// </summary>
		/// <param name="locationCode">位置类型</param>
		/// <param name="position">位置编号</param>
		/// <param name="item">物品</param>
		/// <returns>更新后的货架位置</returns>
		Task<StorageLocation> PlaceItemByPositionAsync(LocationCode locationCode, int position, IStorageItem item);

		/// <summary>
		/// 从指定货架位置取出物品
		/// </summary>
		/// <param name="locationId">货架位置ID</param>
		/// <returns>取出的物品</returns>
		[Obsolete("请使用基于位置的方法 RemoveItemByPositionAsync(LocationCode, int) 代替")]
		Task<IStorageItem?> RemoveItemAsync(int locationId);

		/// <summary>
		/// 从指定货架位置取出物品（通过位置编号）
		/// </summary>
		/// <param name="locationCode">位置类型</param>
		/// <param name="position">位置编号</param>
		/// <returns>取出的物品</returns>
		Task<IStorageItem?> RemoveItemByPositionAsync(LocationCode locationCode, int position);

		/// <summary>
		/// 检查物品是否可以放入指定位置
		/// </summary>
		/// <param name="locationId">位置ID</param>
		/// <param name="itemType">物品类型</param>
		/// <returns>是否可以放入</returns>
		[Obsolete("请使用基于位置的方法 CanPlaceItemTypeByPositionAsync(LocationCode, int, ItemType) 代替")]
		Task<bool> CanPlaceItemTypeAsync(int locationId, ItemType itemType);

		/// <summary>
		/// 检查物品是否可以放入指定位置（通过位置编号）
		/// </summary>
		/// <param name="locationCode">位置类型</param>
		/// <param name="position">位置编号</param>
		/// <param name="itemType">物品类型</param>
		/// <returns>是否可以放入</returns>
		Task<bool> CanPlaceItemTypeByPositionAsync(LocationCode locationCode, int position, ItemType itemType);

		/// <summary>
		/// 获取货架位置的显示名称
		/// 例如：位置101对应货架1-1
		/// </summary>
		/// <param name="position">位置编号</param>
		/// <returns>显示名称</returns>
		string GetShelfDisplayName(int position);

		/// <summary>
		/// 根据显示名称获取货架位置编号
		/// 例如：货架1-1对应位置101
		/// </summary>
		/// <param name="displayName">显示名称</param>
		/// <returns>位置编号</returns>
		int GetShelfPositionFromDisplayName(string displayName);

		/// <summary>
		/// 验证指定名称的物料是否存在于货架上
		/// </summary>
		/// <param name="materialName">物料名称</param>
		/// <param name="functionType">物料功能类型</param>
		/// <returns>是否存在</returns>
		Task<bool> MaterialExistsAsync(string materialName, FunctionType functionType);

		/// <summary>
		/// 验证物料和清洗液是否存在于货架上
		/// </summary>
		/// <param name="materialName">待旋蒸物料名称</param>
		/// <param name="condensationCleaningSolution">冷凝器清洗液名称</param>
		/// <param name="rotaryBottleCleaningSolution">旋蒸瓶清洗液名称</param>
		/// <returns>验证结果和错误信息</returns>
		Task<(bool IsValid, string ErrorMessage)> ValidateMaterialsExistenceAsync(
			string materialName,
			string condensationCleaningSolution,
			string rotaryBottleCleaningSolution);

		/// <summary>
		/// 验证货架上是否有足够的瓶子用于实验
		/// </summary>
		/// <param name="requiredRotovapBottles500ml">所需500ml旋蒸瓶数量</param>
		/// <param name="requiredRotovapBottles1000ml">所需1000ml旋蒸瓶数量</param>
		/// <param name="requiredCentrifugeBottles">所需离心瓶数量</param>
		/// <param name="requiredSampleBottles">所需采样瓶数量</param>
		/// <returns>验证结果和错误信息</returns>
		Task<(bool IsValid, string ErrorMessage)> ValidateBottleAvailabilityAsync(
			int requiredRotovapBottles500ml,
			int requiredRotovapBottles1000ml,
			int requiredCentrifugeBottles,
			int requiredSampleBottles);

		/// <summary>
		/// 更新货架位置信息
		/// </summary>
		/// <param name="location">需要更新的货架位置</param>
		/// <returns>更新任务</returns>
		Task UpdateShelfLocationAsync(StorageLocation location);
	}
}